/*
 *Copyright 2021-2023 NERCIS
 *
 *Licensed under the Apache License, Version 2.0 (the "License");
 *you may not use this file except in compliance with the License.
 *You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 *distributed under the License is distributed on an "AS IS" BASIS,
 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *See the License for the specific language governing permissions and
 *limitations under the License.
 */

package cn.ac.nercis.pes.service.project.imported;

import cn.ac.nercis.pes.model.dto.common.Result;
import cn.ac.nercis.pes.model.dto.project.ImportConflictDTO;
import cn.ac.nercis.pes.model.standard.SystemProcessSDTO;
import cn.ac.nercis.pes.repository.dal.project.SystemProcessRepository;
import cn.ac.nercis.pes.repository.model.project.SystemProcessDO;
import cn.ac.nercis.pes.service.utils.CheckFieldUtils;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 系统进度信息导入服务
 *
 * @author zpy
 * @version 1.0.0
 */
@Slf4j
@Service
public class SystemProcessImportService {
    private final SystemProcessRepository systemProcessRepository;

    @Autowired
    public SystemProcessImportService(SystemProcessRepository systemProcessRepository) {
        this.systemProcessRepository = systemProcessRepository;
    }

    public Result<List<ImportConflictDTO>> checkSystemProcess() {
        return Result.success(Collections.emptyList());
    }

    public Result<String> importSystemProcess(@NonNull String systemId, List<SystemProcessSDTO> process, Boolean cover) {
        List<SystemProcessDO> sourceProcess = this.systemProcessRepository.findAllBySystemId(systemId);
        Result<String> result = Result.success();
        for (SystemProcessSDTO p : process) {
            result = this.importSystemProcess(systemId, p, sourceProcess, cover);
            if (!result.isSuccess()) {
                break;
            }
        }
        return result;
    }

    private Result<String> importSystemProcess(String systemId, @NonNull SystemProcessSDTO importProcess, List<SystemProcessDO> sourceProcess, Boolean cover) {
        SystemProcessDO process = sourceProcess.stream()
                .filter(st -> Objects.equals(st.getState(), importProcess.getState())
                        && StringUtils.equals(st.getName(), importProcess.getName()))
                .findFirst().orElse(null);
        if (Objects.isNull(process)) {
            return createSystemProcess(systemId, importProcess,sourceProcess);
        } else {
            return modifySystemProcess(process, importProcess, cover);
        }
    }

    private Result<String> createSystemProcess(String systemId, SystemProcessSDTO importProcess,
                                               List<SystemProcessDO> sourceProcess) {
        SystemProcessDO process = SystemProcessDO.builder()
                .systemId(systemId)
                .state(importProcess.getState())
                .name(importProcess.getName())
                .finishState(importProcess.getFinishState())
                .build();
        process.setCreateTime(LocalDateTime.now());
        return Optional.of(process)
                .map(this.systemProcessRepository::save)
                .map(data->{
                    sourceProcess.add(data);
                    return Result.success(data.getId());
                })
                .orElse(Result.failed(String.format("导入%s系统进度信息，创建失败", importProcess.getName())));
    }

    private Result<String> modifySystemProcess(SystemProcessDO sourceProcess, SystemProcessSDTO importProcess, Boolean cover) {
        sourceProcess.setFinishState(CheckFieldUtils.applyContent(sourceProcess.getFinishState(), importProcess.getFinishState(), cover));
        sourceProcess.setModifyTime(LocalDateTime.now());
        return Optional.of(sourceProcess)
                .map(this.systemProcessRepository::save)
                .map(SystemProcessDO::getId)
                .map(Result::success)
                .orElse(Result.failed(String.format("导入%s系统进度信息，修改失败", importProcess.getName())));
    }

}
